package com.jimmy.medical.service.impl;

import com.jimmy.medical.base.impl.JpaSpecificationServiceImpl;
import com.jimmy.medical.entity.*;
import com.jimmy.medical.enums.RechargeTypeEnum;
import com.jimmy.medical.model.ContractService;
import com.jimmy.medical.model.MemberService;
import com.jimmy.medical.model.SingleService;
import com.jimmy.medical.repository.*;
import com.jimmy.medical.service.ISaleService;
import com.jimmy.medical.util.CommonUtils;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.IteratorUtils;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.util.List;

@Service
public class SaleServiceImpl extends JpaSpecificationServiceImpl<FlowOrderRepository, FlowOrderRepository, FlowOrder, Long> implements ISaleService {

    @Autowired
    private MemberTypeServiceItemRepository memberTypeServiceItemRepository;
    @Autowired
    private MemberTypeRepository memberTypeRepository;
    @Autowired
    private CommodityRepository commodityRepository;
    @Autowired
    private MemberRepository memberRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private SequencesRepository sequencesRepository;
    @Autowired
    private RechargeRecordRepository rechargeRecordRepository;
    @Autowired
    private RechargeRepository rechargeRepository;
    @Autowired
    private ServiceItemRepository serviceItemRepository;
    @Autowired
    private RechargeRecordServiceItemRepository rechargeRecordServiceItemRepository;
    @Autowired
    private RechargeServiceItemRepository rechargeServiceItemRepository;
    @Autowired
    private ContractRepository contractRepository;
    @Autowired
    private MemberContractRepository memberContractRepository;
    @Autowired
    private OrderRepository orderRepository;

    public List<MemberTypeServiceItem> findAllSingleService() {
        return memberTypeServiceItemRepository.findByMemberType(-1L);
    }

    @Override
    public List<MemberType> findAllMemberType() {
        return memberTypeRepository.findAllByIsApp("1");
    }

    @Override
    public List<Commodity> findAllCommodity() {
        return IteratorUtils.toList(commodityRepository.findAll().iterator());
    }

    @Override
    public RechargeRecordServiceItem getSingleServiceRestCount(SingleService singleService) {
        Member member = memberRepository.findFirstByMobileOrIdCard(singleService.getMobile(), singleService.getIdCardNo());
        if(member == null) {
            return null;
        }
        return rechargeRecordServiceItemRepository.findRestCounts(String.valueOf(RechargeTypeEnum.SINGLE_SERVICE.getKey()), member, singleService.getServiceItemId());
    }

    @Override
    public RechargeRecordServiceItem saveSingleService(SingleService singleService) throws InvocationTargetException, IllegalAccessException {
        User user = userRepository.findOne(singleService.getUserId());

        Member member = initMember(singleService, user);

        //充值记录
        RechargeRecord rechargeRecord = new RechargeRecord();
        rechargeRecord.setSaleUser(user);
        rechargeRecord.setCreateTime(CommonUtils.getNowTimeShortString());
        rechargeRecord.setCreateUser(user.getRealname());
        rechargeRecord.setDescription(singleService.getDescription());
        rechargeRecord.setMember(member);
        rechargeRecord.setMoney(singleService.getMoney());
        rechargeRecord.setRechargeType(String.valueOf(RechargeTypeEnum.SINGLE_SERVICE.getKey()));
        rechargeRecord.setStatus("1");
        rechargeRecordRepository.save(rechargeRecord);

        //会员余额，如果是新会员没有会员余额信息，需要初始化一个
        Recharge recharge = rechargeRepository.findFirstByMemberAndRechargeType(member, String.valueOf(RechargeTypeEnum.SINGLE_SERVICE.getKey()));
        if(recharge == null) {
            recharge = new Recharge();
            BeanUtils.copyProperties(recharge, rechargeRecord);
            rechargeRepository.save(recharge);
        }

        ServiceItem serviceItem = serviceItemRepository.findOne(singleService.getServiceItemId());
        RechargeRecordServiceItem rechargeRecordServiceItem = new RechargeRecordServiceItem();
        rechargeRecordServiceItem.setCounts(1);
        rechargeRecordServiceItem.setItem(serviceItem);
        rechargeRecordServiceItem.setRecord(rechargeRecord);
        rechargeRecordServiceItem.setRestCounts(1);
        rechargeRecordServiceItemRepository.save(rechargeRecordServiceItem);

        RechargeServiceItem rechargeServiceItem = rechargeServiceItemRepository.findFirstByRecharge(recharge);
        if(rechargeServiceItem == null) {
            rechargeServiceItem = new RechargeServiceItem();
            rechargeServiceItem.setItem(serviceItem);
            rechargeServiceItem.setRecharge(recharge);
        }

        //充值之前先判断有无剩余次数，进入充值之后剩余次数一定为0
        rechargeServiceItem.setCounts(1);
        rechargeServiceItemRepository.save(rechargeServiceItem);
        return rechargeRecordServiceItem;
        //记录销售业绩

    }

    @Override
    public RechargeRecord saveContractService(ContractService contractService) throws InvocationTargetException, IllegalAccessException {
        User user = userRepository.findOne(contractService.getUserId());
        Member member = initMember(contractService, user);

        //计算会期
        DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
        if(StringUtils.isBlank(contractService.getBeginTime())) {
            contractService.setBeginTime(CommonUtils.getNowDateNormalString());
        }
        MemberType memberType = memberTypeRepository.findOne(contractService.getMemberTypeId());
        DateTime beginDateTime = formatter.parseDateTime(contractService.getBeginTime());
        DateTime expireDateTime = beginDateTime.plusDays(memberType.getCycle());

        if(StringUtils.isBlank(member.getExpireTime()) || member.getExpireTime().indexOf("-") < 0 || formatter.parseDateTime(member.getExpireTime()).isBefore(expireDateTime)) {
            member.setExpireTime(formatter.print(expireDateTime));
        }

        if(StringUtils.isBlank(member.getBeginTime())) {
            member.setBeginTime(contractService.getBeginTime());
        }

        member.setMemberType(memberType);

        //合同
        Contract contract = new Contract();
        contract.setMember(member);
        contract.setMemberName(member.getRealname());
        contract.setMemberNo(member.getMemberNo());

        contract.setContractNo(generateContractNo());
        contract.setCreateTime(CommonUtils.getNowTimeShortString());
        contract.setCreateUser(user.getRealname());
        contract.setContractType("2");
        contract.setExpireTime(formatter.print(expireDateTime));
        contract.setStartTime(contractService.getBeginTime());
        contract.setStatus("1");
        contract.setMemberType(memberType);
        contractRepository.save(contract);

        MemberContract mc = new MemberContract();
        mc.setContract(contract);
        mc.setMember(member);
        memberContractRepository.save(mc);

        RechargeRecord rechargeRecord = new RechargeRecord();
        rechargeRecord.setSaleUser(user);
        rechargeRecord.setStatus("1");
        rechargeRecord.setRechargeType(String.valueOf(RechargeTypeEnum.CONTRACT.getKey()));
        rechargeRecord.setMoney(contractService.getMoney());
        rechargeRecord.setMember(member);
        rechargeRecord.setDescription(contractService.getDescription());
        rechargeRecord.setCreateUser(user.getRealname());
        rechargeRecord.setCreateTime(CommonUtils.getNowTimeShortString());
        rechargeRecord.setBeginTime(contract.getStartTime());
        rechargeRecord.setContract(contract);
        rechargeRecord.setCycle(memberType.getCycle());
        rechargeRecord.setExpireTime(contract.getExpireTime());
        rechargeRecordRepository.save(rechargeRecord);

        Recharge recharge = rechargeRepository.findFirstByMemberAndRechargeType(member, String.valueOf(RechargeTypeEnum.CONTRACT.getKey()));
        if(recharge == null) {
            recharge = new Recharge();
            BeanUtils.copyProperties(recharge, rechargeRecord);
            rechargeRepository.save(recharge);
        }

        List<MemberTypeServiceItem> memberTypeServiceItemList = memberTypeServiceItemRepository.findByMemberType(memberType.getId());
        for(MemberTypeServiceItem item : memberTypeServiceItemList) {
            //将会员类型包含的服务全部加入会员余额中
            RechargeRecordServiceItem rechargeRecordServiceItem = new RechargeRecordServiceItem();
            rechargeRecordServiceItem.setRecord(rechargeRecord);
            rechargeRecordServiceItem.setRestCounts(item.getCounts());
            rechargeRecordServiceItem.setItem(item.getItem());
            rechargeRecordServiceItem.setCounts(item.getCounts());
            rechargeRecordServiceItemRepository.save(rechargeRecordServiceItem);

            RechargeServiceItem rechargeServiceItem = rechargeServiceItemRepository.findFirstByRechargeAndItem(recharge, item.getItem());
            if(rechargeServiceItem == null) {
                rechargeServiceItem = new RechargeServiceItem();
                rechargeServiceItem.setRecharge(recharge);
                rechargeServiceItem.setItem(item.getItem());
                rechargeServiceItem.setCounts(item.getCounts());
            } else {
                rechargeServiceItem.setCounts(rechargeServiceItem.getCounts() + item.getCounts());
            }

            rechargeServiceItemRepository.save(rechargeServiceItem);
        }

        return rechargeRecord;
    }

    @Override
    public String savePayOrderNo(Long flowOrderId) {
        FlowOrder flowOrder = repository.findOne(flowOrderId);
        Order order = flowOrder.getOrder();
        order.setPayFlowNo(generatePayFlowNo());
        orderRepository.save(order);

        return order.getPayFlowNo();
    }

    @Override
    public String savePaySingleServiceNo(Long singleServiceId) {
        RechargeRecord singleService = rechargeRecordRepository.findOne(singleServiceId);
        singleService.setPayFlowNo(generatePayFlowNo());
        rechargeRecordRepository.save(singleService);

        return singleService.getPayFlowNo();
    }

    @Override
    public String savePayContractNo(Long contractId) {
        RechargeRecord contract = rechargeRecordRepository.findOne(contractId);
        contract.setPayFlowNo(generatePayFlowNo());
        rechargeRecordRepository.save(contract);

        return contract.getPayFlowNo();
    }

    private Member initMember(MemberService memberService, User user) {
        //会员
        Member member = memberRepository.findFirstByMobileOrIdCard(memberService.getMobile(), memberService.getIdCardNo());

        if (member == null) {
            member = new Member();
            member.setMemberNo(generateMemberNo());
            member.setCreateTime(CommonUtils.getNowTimeShortString());
            member.setCreateUser(user.getRealname());
        }

        member.setMobile(memberService.getMobile());
        member.setIdCard(memberService.getIdCardNo());
        member.setRealname(memberService.getName());
        memberRepository.save(member);

        return member;
    }

    private String generateMemberNo() {
        return generateSysNo(CommonUtils.getNowDateShortString(), "YK");
    }

    private String generateContractNo() {
        return generateSysNo(CommonUtils.getNowDateShortString(), "HT");
    }

    /**
     * 支付流水号
     * @return
     */
    private String generatePayFlowNo() {
        return generateSysNo(CommonUtils.getNowDateShortString(), "ZF");
    }

    private String generateSysNo(String nowDay, String prefix) {
        Sequences sequences = sequencesRepository.findFirstByDate(nowDay);
        int currentSeq = 0;
        if (sequences != null) {
            currentSeq = sequences.getSeq();
        } else {
            sequences = new Sequences();
            sequences.setDate(CommonUtils.getNowDateNormalString());
        }

        sequences.setSeq(currentSeq + 1);
        sequencesRepository.save(sequences);
        String seqStr = String.valueOf(sequences.getSeq());
        while (seqStr.length() < 4) {
            seqStr = "0" + seqStr;
        }

        return prefix + nowDay + seqStr;
    }
}
